package org.zjx.core;

import lombok.Data;
import lombok.Getter;
import org.zjx.command.ICommand;
import java.awt.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 窗口会话 - 增加引用计数和状态管理（整改后版本）
 */
@Data
public class WindowSession {
    private final String sessionId;
    private final ScreenWindow screenWindow;
    private GameWindow gameWindow;
    private volatile SessionState state = SessionState.CREATED;
    /**
     * -- GETTER --
     *  获取最后活动时间
     */
    @Getter
    private volatile long lastActivityTime;
    private final AtomicInteger referenceCount = new AtomicInteger(0);
    private final ReentrantLock lock = new ReentrantLock();
    private volatile boolean singleTaskSession = true;

    // Session状态枚举
    public enum SessionState {
        CREATED,    // 已创建
        ACTIVE,     // 活跃中（有命令在执行）
        IDLE,       // 空闲（无命令但未超时）
        CLOSING,    // 关闭中
        CLOSED      // 已关闭
    }

    public WindowSession(String sessionId, Rectangle bounds) {
        this.sessionId = sessionId;
        this.screenWindow = new ScreenWindow("Screen-" + sessionId, bounds, this);
        this.lastActivityTime = System.currentTimeMillis();
        this.state = SessionState.CREATED;
        System.out.println("[WindowSession] Created session: " + sessionId);
    }

    /**
     * 绑定窗口
     */
    public boolean bindWindow(GameWindow gameWindow) {
        lock.lock();
        try {
            if (this.gameWindow != null) {
                System.err.println("[WindowSession] Session already bound to: " + this.gameWindow.getId());
                return false;
            }

            if (gameWindow == null) {
                System.err.println("[WindowSession] Cannot bind null window");
                return false;
            }

            this.gameWindow = gameWindow;
            gameWindow.setCurrentSession(this);
            screenWindow.setBoundWindow(gameWindow);
            this.state = SessionState.ACTIVE;

            System.out.println("[WindowSession] Successfully bound window: " +
                    gameWindow.getId() + " to session: " + sessionId);
            return true;
        } finally {
            lock.unlock();
        }
    }

    /**
     * 提交指令（增加引用计数）
     */
    public boolean submitCommand(ICommand command) {
        lock.lock();
        try {
            if (state == SessionState.CLOSING || state == SessionState.CLOSED) {
                System.err.println("[WindowSession] Cannot submit command to closing/closed session: " + sessionId);
                return false;
            }

            if (screenWindow.submitCommand(command)) {
                referenceCount.incrementAndGet();
                lastActivityTime = System.currentTimeMillis();
                state = SessionState.ACTIVE;
                return true;
            }
            return false;
        } finally {
            lock.unlock();
        }
    }

    /**
     * 命令执行完成（减少引用计数）
     */
    public void commandCompleted() {
        lock.lock();
        try {
            int count = referenceCount.decrementAndGet();
            lastActivityTime = System.currentTimeMillis();

            System.out.println("[WindowSession] Command completed, refCount: " + count +
                    " for session: " + sessionId);

            if (count == 0) {
                state = SessionState.IDLE;
                System.out.println("[WindowSession] Session " + sessionId + " became idle");
            } else if (count < 0) {
                // 防止引用计数为负数
                referenceCount.set(0);
                state = SessionState.IDLE;
                System.out.println("[WindowSession] WARNING: RefCount negative, reset to 0 for session: " + sessionId);
            }
        } finally {
            lock.unlock();
        }
    }

    /**
     * 获取当前引用计数
     */
    public int getReferenceCount() {
        return referenceCount.get();
    }

    /**
     * 安全解绑窗口
     */
    public void unbindWindow() {
        lock.lock();
        try {
            if (state == SessionState.CLOSED) {
                return;
            }

            state = SessionState.CLOSING;
            System.out.println("[WindowSession] Unbinding session: " + sessionId +
                    ", refCount: " + referenceCount.get());

            // 安全关闭屏幕窗口
            if (screenWindow != null) {
                screenWindow.shutdown();
            }

            // 解绑游戏窗口
            if (gameWindow != null) {
                gameWindow.setCurrentSession(null);
                if (screenWindow != null) {
                    screenWindow.setBoundWindow(null);
                }
                gameWindow = null;
            }

            state = SessionState.CLOSED;
            System.out.println("[WindowSession] Session " + sessionId + " closed completely");
        } finally {
            lock.unlock();
        }
    }

    /**
     * 强制立即关闭（不管引用计数）
     */
    public void forceClose() {
        lock.lock();
        try {
            System.out.println("[WindowSession] Force closing session: " + sessionId +
                    ", refCount: " + referenceCount.get());

            // 立即清空命令队列
            if (screenWindow != null) {
                screenWindow.forceShutdown();
            }

            // 解绑窗口
            if (gameWindow != null) {
                gameWindow.setCurrentSession(null);
                gameWindow = null;
            }

            state = SessionState.CLOSED;
            System.out.println("[WindowSession] Session " + sessionId + " force closed");
        } finally {
            lock.unlock();
        }
    }

    /**
     * 检查是否可以安全关闭
     */
    public boolean canSafeClose() {
        return referenceCount.get() == 0 &&
                (System.currentTimeMillis() - lastActivityTime) > 5000; // 5秒空闲
    }

    /**
     * 检查是否需要强制关闭（僵尸Session）
     */
    public boolean needForceClose(long timeoutMs) {
        return state == SessionState.ACTIVE &&
                (System.currentTimeMillis() - lastActivityTime) > timeoutMs;
    }

    /**
     * 检查是否活跃
     */
    public boolean isActive() {
        return state == SessionState.ACTIVE || state == SessionState.IDLE;
    }

    /**
     * 获取命令计数
     */
    public int getCommandCount() {
        return referenceCount.get();
    }

    /**
     * 设置命令计数
     */
    public void setCommandCount(int count) {
        referenceCount.set(count);
    }
}